#include <enet/enet.h>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>

using namespace std;
struct xnet
{
    ENetHost * server, * client;
    ENetPeer * peer;
	xnet()
	{
        printf("init...\n");

		if (enet_initialize() != 0)
        {
            cout << "An error occurred while initializing ENet.\n" << endl;
            exit (EXIT_FAILURE);
        }
        
        ENetAddress addr;
        addr.port = 1234;
        addr.host= ENET_HOST_ANY;
        printf("creating server\n");
	    server = enet_host_create (& addr, 32, 2, 0, 0);
	    if (server == NULL)
        {
            cout << "An error occurred while trying to create an ENet server host." << endl;
            exit (EXIT_FAILURE);
        }
        printf("creating client\n");
	    client = enet_host_create (NULL, 1, 2, 57600/8, 14400/8);
	    if (client == NULL)
        {
            cout << "An error occurred while trying to create an ENet client host." << endl;
            exit (EXIT_FAILURE);
        }
        printf("init finished !\n");

	}
	void finish()
	{
        ENetEvent event;
        
        enet_peer_disconnect (peer, 0);
        /* Allow up to 3 seconds for the disconnect to succeed
         and drop any packets received packets.
         */
        while (enet_host_service (client, & event, 3000) > 0)
        {
            switch (event.type)
            {
                case ENET_EVENT_TYPE_RECEIVE:
                    enet_packet_destroy (event.packet);
                    break;
                case ENET_EVENT_TYPE_DISCONNECT:
                    puts ("Disconnection succeeded.");
                    break;
            }
        }
        
        /* We've arrived here, so the disconnect attempt didn't */
        /* succeed yet.  Force the connection down.             */
        enet_peer_reset (peer);

	    enet_host_destroy(client);
	    enet_host_destroy(server);

	    enet_deinitialize();	
	}
	void receive(int poll_time)
	{
        ENetEvent event;
        int ret = enet_host_service (client, & event, poll_time);
		if (ret > 0)
    	{
	        switch (event.type)
	        {
	        case ENET_EVENT_TYPE_CONNECT:
	            printf ("A new client connected from %x:%u.\n", 
	                    event.peer -> address.host,
	                    event.peer -> address.port);
	            /* Store any relevant client information here. */
	            event.peer -> data = (void*)("Client information");
	            break;

            case ENET_EVENT_TYPE_RECEIVE:
	            printf ("A packet of length %u containing %s was received from %s on channel %u.\n",
	                    event.packet -> dataLength,
	                    event.packet -> data,
	                    event.peer -> data,
	                    event.channelID);
	            /* Clean up the packet now that we're done using it. */
	            enet_packet_destroy (event.packet);
	            break;
	           
	        case ENET_EVENT_TYPE_DISCONNECT:
	            printf ("%s disconected.\n", event.peer -> data);
	            /* Reset the peer's client information. */
	            event.peer -> data = NULL;
        	}
    	}
        else
        if(ret == 0)
            printf(".");
        else
            if(ret < 0)
                cout << "receive error" << endl;
            
	}
    void send(char * s)
    {
        printf("creating packet\n");
        ENetPacket * packet =
            enet_packet_create((void*)s, strlen(s), ENET_PACKET_FLAG_RELIABLE);
        printf("sending %s\n", s);
        enet_peer_send(peer, 0, packet);
    }
	void add(char * s, int pool_time)
	{
        ENetAddress addr;
        ENetEvent event;
        printf("reading address\n");
        enet_address_set_host(&addr, s);

        addr.port = 1234;
        printf("connecting...\n");
        peer = enet_host_connect(client, &addr, 2, 0);
        if(peer == NULL)
            cout << "An error occurred while trying to create an ENet client host." << endl;
        printf("evaluating connect event...\n");
        if (enet_host_service (client, & event, pool_time) > 0 &&
            event.type == ENET_EVENT_TYPE_CONNECT)
            puts ("Connection succeeded.");
        else
        {
            /* Either the 5 seconds are up or a disconnect event was */
            /* received. Reset the peer in the event the 5 seconds   */
            /* had run out without any significant event.            */
            enet_peer_reset (peer);
            puts ("Connection failed.");
        }
    }
};